package com.yun.blog.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yun.blog.bean.User;
import com.yun.blog.bean.response.GiteeUserInfo;
import com.yun.blog.bean.response.OauthResponse;
import com.yun.blog.bean.response.OauthUserInfo;
import com.yun.blog.config.oauth.GiteeProperties;
import com.yun.blog.service.OauthService;
import com.yun.blog.service.UserService;
import com.yun.blog.utils.HttpUtils;
import com.yun.blog.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author : simple
 * @title : GiteeOauthServiceImpl
 * @projectName : dantouBlog-back
 * @description : gitee 认证实现类
 * @email : yun_simple@163.com
 * @date : 2023/5/21下午9:33
 */

@Service("giteeOauth")
@Slf4j
public class GiteeOauthServiceImpl implements OauthService {

    @Resource
    private GiteeProperties giteeProperties;

    @Resource
    private UserService userService;

    @Override
    public String getOauthUrl() {
        try {
            return "https://gitee.com/oauth/authorize?" +
                    "client_id=" + giteeProperties.getClientId() +
                    "&response_type=code" +
                    "&redirect_uri=" + URLEncoder.encode(giteeProperties.getRedirectUri(), "utf-8") +
                    "&scope=user_info emails";
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public OauthResponse code2Token(String code) {
        HashMap<String, String> params = new HashMap<>();
        params.put("grant_type", "authorization_code");
        params.put("code", code);
        params.put("client_id", giteeProperties.getClientId());
        params.put("client_secret", giteeProperties.getClientSecret());
        params.put("redirect_uri", giteeProperties.getRedirectUri());
        String res = HttpUtils.post(giteeProperties.getAccessTokenUrl(), params);
        OauthResponse oauthResponse = JSON.parseObject(res, OauthResponse.class);
        log.info("gitee 授权得到的响应：{}", oauthResponse);
        if (oauthResponse.getError() != null) {
            throw new RuntimeException(oauthResponse.getErrorDescription());
        }
        return oauthResponse;
    }

    /**
     * 返回第三方登录的用户信息
     *
     * @param oauthResponse 获取token时候的响应数据
     * @return OauthUserInfo
     * @author yun
     * @date 2023/6/6 下午10:08
     */
    @Override
    public OauthUserInfo getUserInfo(OauthResponse oauthResponse) {
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("access_token", oauthResponse.getAccessToken()));
        String res = HttpUtils.get(giteeProperties.getUserInfoUrl(), null, params);
        log.info("用户信息为：{}", res);
        return JSON.parseObject(res, GiteeUserInfo.class);
    }


    @Override
    public HashMap<String, Object> login(String code) {
        OauthResponse oauthResponse = code2Token(code);
        GiteeUserInfo userInfo = (GiteeUserInfo) getUserInfo(oauthResponse);
        // openid查找用户
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
        // gitee 登录没有openid，直接获取到用户的id，将id存到openid位置
        queryWrapper.eq(User::getOpenId, String.valueOf(userInfo.getId()));
        User user = userService.getOne(queryWrapper);

        // 找到用户就登录,找不到就创建并保存新用户
        if (user != null) {
            if (user.getIsLock()) {
                throw new RuntimeException("账号已锁定，没有登录权限！");
            }
            // 更新最后登录时间
            userService.updateLastLoginTimeByUserId(user.getUserId());
        } else {
            user = new User();
            BeanUtils.copyProperties(userInfo, user);
            BeanUtils.copyProperties(oauthResponse, user);
            user.setOpenId(String.valueOf(userInfo.getId()));
            user.setIsSuperuser(false);
            user.setIsLock(false);
            user.setExpiresIn(new Date(System.currentTimeMillis() + oauthResponse.getExpiresIn()));
            userService.save(user);
        }

        // 设置token
        String token = JwtUtils.getToken(user.getUserId(), user.getUserUsername(), user.getUserNickName());
        HashMap<String, Object> dateMap = new HashMap<>();
        dateMap.put("token", token);
        dateMap.put("userInfo", user);
        return dateMap;
    }
}
